#include "typedef.h"
#include "tester.h"
#include "strapi.h"
#include "kernel/astralapi.h"

static struct AstralSem sem;

int taska_entry(object arg)
{
    AstralTask self = get_curr_task();
    int runtime = self->run_times;
    int delta = 0;

    kprint("[%s] job-%d current run %d times\n",
           self->name,
           CAST_AS(int, arg),
           runtime);

    while (delta < 10)
    {
        delta = self->run_times - runtime;
    }

    kprint("[%s] job-%d runs another %d times\n",
           self->name,
           CAST_AS(int, arg),
           delta);

    release_sem(&sem);
    return 0;
}

#define N (4)


static void description()
{
    kprint("\n\nTick Test\n"
           "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"
           "%d Tasks named tick-xxx will be created.\n"
           "each task finishs when it runs more than 10 times\n\n",
           N);
}

boolean tick_test(object arg)
{
    static boolean first = True;
    if(first)
    {
        create_sem(&sem);
        first = False;
    }
    description();

#ifdef CFG_NO_TASK_POOL
    static struct AstralTask tasks[N];
    static char stack[N][1024];
    char localname[15];
    for (int i = 0; i < N; i++)
    {
        snprintf(localname, 15, "tick-%-03d", i);
        struct AstralAttr attr = {
            .base = &stack[i],
            .stack_size = 1024,
            .priority = 15 + i % 3,
            .name = localname};
        create_task(&tasks[i], &attr, taska_entry, CAST_AS(object, i));
    }
    for (int i = 0; i < N; i++)
    {
        distach_task(&tasks[i]);
    }
#else
    for (int i = 0; i < N; i++)
    {
        pool_dispatch_job(arg, taska_entry, CAST_AS(object, i));
    }
#endif

    for (int i = 0; i < N; i++)
    {
        obtain_sem(&sem);
    }
    
    return True;
}

DEFINE_TEST(tick_test)